package com.dd.admin.business.pay.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.dd.admin.business.card.entity.Card;
import com.dd.admin.business.card.service.CardService;
import com.dd.admin.business.detailServer.entity.SellDetailServer;
import com.dd.admin.business.detailServer.service.SellDetailServerService;
import com.dd.admin.business.memberCard.domain.MemberCardVo;
import com.dd.admin.business.memberCard.entity.MemberCard;
import com.dd.admin.business.memberCard.service.MemberCardService;
import com.dd.admin.business.pay.domain.*;
import com.dd.admin.business.pay.service.AddSellDetailService;
import com.dd.admin.business.pay.service.PayService;
import com.dd.admin.business.product.entity.Product;
import com.dd.admin.business.product.service.ProductService;
import com.dd.admin.business.sell.entity.Sell;
import com.dd.admin.business.sell.service.SellService;
import com.dd.admin.business.sellDetail.entity.SellDetail;
import com.dd.admin.business.sellDetail.service.SellDetailService;
import com.dd.admin.business.sellPay.entity.Sellpay;
import com.dd.admin.business.sellPay.service.SellpayService;
import com.dd.admin.business.server.domain.ServerVo;
import com.dd.admin.business.stock.entity.Stock;
import com.dd.admin.business.stock.service.StockService;
import com.dd.admin.business.stockDetail.entity.StockDetail;
import com.dd.admin.business.stockDetail.service.StockDetailService;
import com.dd.admin.common.exception.ApiException;
import com.dd.admin.common.security.SecurityUtil;
import com.dd.admin.common.utils.BigDecimalUtil;
import com.dd.admin.common.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.dd.admin.business.pay.enmus.CashierExceptionEnum.*;
import static com.dd.admin.business.pay.enmus.PayConst.*;
import static com.dd.admin.common.consts.MemberShopConst.*;

@Service
public class SellDetailMemberProduct implements AddSellDetailService {

    @Autowired
    private MemberCardService memberCardService;
    @Autowired
    private SellDetailService sellDetailService;
    @Autowired
    private SellpayService sellpayService;
    @Autowired
    private PayService payService;
    @Autowired
    private ProductService productService;
    @Autowired
    private StockService stockService;
    @Autowired
    private StockDetailService stockDetailService;
    @Autowired
    private SellDetailServerService sellDetailServerService;
    @Override
    public void addSellDetail(Sell sell, BaseSell sellDto) {
        MemberProductSell memberProductSell = (MemberProductSell) sellDto;
        String memberCardId = memberProductSell.getMemberCardId();
        MemberCard memberCard = null;
        BigDecimal memberBeforeAmount = null;
        BigDecimal memberBeforeGiveAmount = null;

        //如果有会员卡
        if(StringUtil.isNotEmpty(memberCardId)){
            //先获取消费前前金额
            MemberCard memberHistoryCard = memberCardService.getById(memberCardId);
            memberBeforeAmount = memberHistoryCard.getAmount();
            memberBeforeGiveAmount = memberHistoryCard.getGiveAmount();

            //扣款
            memberCard = deductMemberCard(memberHistoryCard,memberProductSell.getSellPayList());
        }

        //添加支付方式
        sellpayService.addSellPayList(memberProductSell.getSellPayList(),sell.getSellId());

        //订单详情
        List<SellDetail> selldetailList = new ArrayList<>();

        //获取订单详情
       List<ProductForm> productDetailFormList = memberProductSell.getProductFormList();
        MemberCard finalMemberCard = memberCard;
        //设置细单会员余额
        BigDecimal finalMemberBeforeAmount = memberBeforeAmount;
        BigDecimal finalMemberBeforeGiveAmount = memberBeforeGiveAmount;
        productDetailFormList.stream().forEach(productSellDetail -> {
            SellDetail selldetail = addSellDetail(productSellDetail,sell, finalMemberCard, finalMemberBeforeAmount, finalMemberBeforeGiveAmount);
            selldetailList.add(selldetail);
        });

        payService.setSellExtraInfo(sell.getSellId(),memberCard,memberBeforeAmount,memberBeforeGiveAmount);
    }

    //添加详情
    SellDetail addSellDetail(ProductForm productDetail , Sell sell, MemberCard memberCard,BigDecimal memberBeforeAmount,BigDecimal memberBeforeGiveAmount ){
        SellDetail sellDetail = new SellDetail();
        //3设置订单id 订单类型 订单状态
        sellDetail.setSellId(sell.getSellId());
        sellDetail.setSellType(sell.getSellType());
        sellDetail.setSellStatus(sell.getSellStatus());
        sellDetail.setMemberId(sell.getMemberId());


        //设置商品信息
        sellDetail.setProductType(PRODUCT_TYPE_PRODUCT);
        sellDetail.setProductId(productDetail.getProductId());
        sellDetail.setProductName(productDetail.getProductName());
        sellDetail.setAmount(productDetail.getProductAmount());
        sellDetail.setDiscount(productDetail.getDiscount());
        sellDetail.setCount(productDetail.getCount());
        sellDetail.setRealAmount(productDetail.getRealAmount());
        sellDetail.setTotalRealAmount(productDetail.getTotalRealAmount());
        //设置会员信息
        if(memberCard!=null){
            sellDetail.setCardId(memberCard.getCardId());
            sellDetail.setMemberCardId(memberCard.getMemberCardId());
        }


        Product product = productService.getById(productDetail.getProductId());

        //减去库存信息
        if(product.getStockControl().equals(STOCK_CONTROL_YES)) {
            //创建入库总单
            Stock stock = new Stock();
            stock.setStockOutType(STOCK_OUT_TYPE_USE);
            stock.setStockTitle(DateUtil.formatChineseDate(new Date(), false, true) + SecurityUtil.getLoginUser().getDeptName() + "出库单");
            stock.setStockNo(StringUtil.getDateStringNow() + StringUtil.createCode(4));
            stock.setStockType(STOCK_OUT);
            stockService.save(stock);

            StockDetail stockDetail = new StockDetail();
            stockDetail.setStockId(stock.getStockId());
            stockDetail.setProductId(product.getProductId());
            stockDetail.setProductName(product.getProductName());
            stockDetail.setCount(productDetail.getCount());

            productService.subProductCount(product.getProductId(), productDetail.getCount());

            stockDetailService.save(stockDetail);
        }

        sellDetailService.save(sellDetail);

        //该条目有服务人员
        List<ServerVo> serverList = productDetail.getServerList();
        if(CollectionUtil.isNotEmpty(serverList)) {
            //如果是固定金额 固定金额除以人数 获取固定金额
            //如果是比例 计算出比例后提成 获取固定金额
            //业绩和提成均平均分
            //总提成
            BigDecimal totalPushMoney = BigDecimal.ZERO;
            //总业绩 为订单实付金额
            BigDecimal totalGradeMoney = sellDetail.getTotalRealAmount();
            //固定金额的话
            if (product.getPushType().equals(PUSH_FIXED)) {
                totalPushMoney = BigDecimalUtil.mul(product.getPushAmount(),new BigDecimal(sellDetail.getCount()));

            }
            //按比例
            if (product.getPushType().equals(PUSH_SCALE)) {
                //提成额 先转换为百分数
                BigDecimal pushPercent = BigDecimalUtil.div(product.getPushPercent(), new BigDecimal("100"));
                //折后价*百分数
                totalPushMoney = BigDecimalUtil.mul(totalGradeMoney, pushPercent);
            }


            //平均分
            BigDecimal pushMoney = BigDecimalUtil.div(totalPushMoney, new BigDecimal(serverList.size()));
            BigDecimal gradeMoney = BigDecimalUtil.div(totalGradeMoney, new BigDecimal(serverList.size()));


            //设置服务人员
            serverList.stream().forEach(server -> {
                SellDetailServer sellDetailServer = new SellDetailServer();
                sellDetailServer.setSellId(sell.getSellId());
                sellDetailServer.setSellDetailId(sellDetail.getSellDetailId());
                sellDetailServer.setServerId(server.getServerId());
                sellDetailServer.setServerName(server.getServerName());
                sellDetailServer.setServerPushMoney(pushMoney);
                sellDetailServer.setServerGrade(gradeMoney);
                sellDetailServerService.save(sellDetailServer);
            });

        }
        return sellDetail;
    }



    //减去卡金
    MemberCard deductMemberCard(MemberCard memberHistoryCard, List<Sellpay> sellPayList){
        //消费前会员卡余额
        BigDecimal memberBeforeAmount = memberHistoryCard.getAmount();
        BigDecimal memberBeforeGiveAmount = memberHistoryCard.getGiveAmount();
        BigDecimal memberBeforeTotalAmount = BigDecimalUtil.add(memberBeforeAmount,memberBeforeGiveAmount);
        //订单需要支付的卡金
        BigDecimal memberCardCost = sellPayList.stream()
                .filter(p -> p.getPayType().equals(PAY_TYPE_CARD))
                .map(Sellpay::getAmount)
                .findFirst().orElse(BigDecimal.ZERO);
        //订单需要支付的金额 先扣卡金 退款仅退卡金
        //如果卡金足够支付
        try {
            if(memberBeforeAmount.compareTo(memberCardCost) > -1){
                BigDecimal memberAfterAmount = BigDecimalUtil.sub(memberBeforeAmount, memberCardCost);
                memberHistoryCard.setAmount(memberAfterAmount);
                //卡总金额是否够支付
            }else if(memberBeforeTotalAmount.compareTo(memberCardCost) > -1){
                //这里已经出现了卡金不够支付的情况了 所以置为0 减去的金额是赠送金需要支付的
                BigDecimal memberCardGiveCost = BigDecimalUtil.sub(memberCardCost, memberBeforeAmount);

                sellPayList.stream().forEach(sellpay -> {
                    if(sellpay.getPayType().equals(PAY_TYPE_CARD)){
                        sellpay.setAmount(memberBeforeAmount);
                    }
                });

                memberHistoryCard.setAmount(BigDecimal.ZERO);

                if(memberBeforeGiveAmount.compareTo(memberCardGiveCost) > -1){
                    Sellpay sellpay = new Sellpay();
                    sellpay.setPayType(PAY_TYPE_CARD_GIVE);
                    sellpay.setAmount(memberCardGiveCost);
                    sellpay.setPayName(PAY_TYPE_CARD_GIVE_NAME);
                    sellPayList.add(sellpay);

                    BigDecimal memAfterGiveAmount = BigDecimalUtil.sub(memberBeforeGiveAmount, memberCardGiveCost);
                    memberHistoryCard.setGiveAmount(memAfterGiveAmount);
                }
            }else{
                throw new ApiException(MEMBER_CARD_NOT_SUFFICIENT_FUNDS);
            }

            Boolean b = memberCardService.updateById(memberHistoryCard);
            //监听数据 乐观锁改变
            if(!b){
                throw new ApiException(CARD_AMOUNT_CHANGE);
            }
        }catch (ArithmeticException e) {
            // 处理数值计算异常，并提供更详细的错误信息
            throw new RuntimeException("数值计算出现异常：" + e.getMessage(), e);
        }

        return memberHistoryCard;
    }
}
